#!/usr/bin/python
# -*- coding: ascii -*-

# Narodmon sender
# version 1.4

import OpenOPC
import time
import socket
import signal
import sys
from datetime import datetime

opc_server_name = "OpenOPC"
opc_tag = "Group.Sensor.Out1"
ip_address = "185.245.187.136"
port = 8283
mak = "MY-DEVICE"

def reconnect_opc(max_retries, log_file):
  retries = 0
  while True:
    try:
      opc = OpenOPC.client()
      opc.connect(opc_server_name)
      log_file.write("{} - OPC connected successfully\n".format(datetime.now()))
      return opc
    except Exception as e:
      retries += 1
      log_file.write("{} - OPC Connection failed. Retry attempt: {}\n".format(datetime.now(), retries))
      if retries == max_retries:
        log_file.write('Max retries exceeded. Exiting...\n')
        sys.exit(1)
      time.sleep(5)

def reconnect_socket(max_retries, log_file):
  retries = 0
  while True:
    try:
      s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      addr = (ip_address, port)
      if s.connect_ex(addr) != 0:
        s.close()
        raise Exception('Socket connection failed')
      log_file.write("{} - Socket connected successfully\n".format(datetime.now()))
      return s
    except Exception as e:
      retries += 1
      log_file.write("{} - Socket Connection failed. Retry attempt: {}\n".format(datetime.now(), retries))
      if retries == max_retries:
        log_file.write('Max retries exceeded. Exiting...\n')
        sys.exit(1)
      time.sleep(5)

def signal_handler(sig, frame):
  print('Program terminated')
  sys.exit(0)

max_retries = 3
log_file_path = 'log.txt'
signal.signal(signal.SIGINT, signal_handler)
addr = (ip_address, port)
while True:
  try:
    with open(log_file_path, 'a') as log_file:
      opc = reconnect_opc(max_retries, log_file)
      s = reconnect_socket(max_retries, log_file)

      val = opc[opc_tag]
      buf = "#" + mak + "\n#T1#" + "%.1f#" % val + "\n##"
      s.sendto(buf.encode(), addr)
      opc.close()
      s.close()
      log_file.write("{} - Data sent successfully\n".format(datetime.now()))

  except Exception as e:
    with open(log_file_path, 'a') as log_file:
      log_file.write("{} - Error: {}\n".format(datetime.now(), str(e)))

  time.sleep(180)
